home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Ham Radio 2000 #2
/
Ham Radio 2000 - Volume 2.iso
/
HAMV2
/
TCP_IP
/
TNOS230S
/
IFACE.C
< prev
next >
Wrap
C/C++ Source or Header
|
1997-09-06
|
23KB
|
921 lines
/* IP interface control and configuration routines
* Copyright 1991 Phil Karn, KA9Q
*
* Mods by PA0GRI
*/
#include "global.h"
#include "ctype.h"
#include "commands.h"
#include "mbuf.h"
#include "proc.h"
#ifndef MSDOS
#include "iface.h"
#endif
#ifdef ETHER
#include "enet.h"
#endif
#include "arp.h"
#include "pktdrvr.h"
#include "nr4.h"
#include "mailbox.h"
#if !defined(_lint)
static char rcsid[] OPTIONAL = "$Id: iface.c,v 1.25 1997/09/07 00:31:16 root Exp root $";
#endif
#ifdef NETROM
extern struct iface *Nr_iface;
extern char Nralias[];
#endif
static void showiface (struct iface * ifp);
static int ifipaddr (int argc, char *argv[], void *p);
static int ifipcall (int argc, char *argv[], void *p);
static int iflinkadr (int argc, char *argv[], void *p);
static int ifbroad (int argc, char *argv[], void *p);
static int ifnetmsk (int argc, char *argv[], void *p);
static int ifmtu (int argc, char *argv[], void *p);
static int ifmetric (int argc, char *argv[], void *p);
static int ifforw (int argc, char *argv[], void *p);
static int ifencap (int argc, char *argv[], void *p);
static int ifdescr (int argc, char *argv[], void *p);
#ifdef RXECHO
static int ifrxecho (int argc, char *argv[], void *p);
#endif
static const char subcommands[] = "valid subcommands:\n";
static const char nochangeIP[] = "Cannot change IP address !\n";
static const char setIPcall[] = "Can't set IP call\n";
static const char setlinkaddr[] = "Can't set link address\n";
static const char encaperr[] = "Encapsulation mode '%s' unknown\n";
static const char notsametype[] = "'%s not the same type!\n";
static const char showfmt[] = "%-10s IP addr %s MTU %u Metric %d Link encap ";
static const char notset[] = "not set\n";
static const char showlink[] = " Link addr %s";
static const char showsent[] = " sent: ip %lu tot %lu idle %s\n";
static const char showrecv[] = " recv: ip %lu tot %lu idle %s\n";
static const char showdescr[] = " descr: %s";
static const char detnope[] = "Can't detach loopback or encap interface\n";
static const char showflags[] = " flags 0x%lx trace 0x%x netmask 0x%08lx broadcast %s\n";
static const char showforw[] = " output forward to %s\n";
#ifdef AX25
static const char showIPcall[] = " IP call %s";
static const char showlenirtt[] = " Paclen %d Irtt %lu\n";
static const char showbctext[] = " BCText: %s\n";
static const char showremote[] = " Remote call %s";
#ifdef AXIP
static const char showremoteIP[] = " Remote IP addr %s\n";
#endif
#endif
#ifdef RXECHO
static const char showrxecho[] = " rx packets echoed to %s\n";
#endif
struct iftcp def_iftcp = {DEF_RTT, 0L, DEF_WND, DEF_MSS, 31, DEF_RETRIES, 0, 0};
/* Interface list header */
struct iface *Ifaces = &Loopback;
#ifdef AXIP
extern uint32 *axipaddr; /* table of IP addresses of AX.25 interfaces */
#endif
/* Loopback pseudo-interface */
struct iface Loopback =
{
#ifdef ENCAP
&Encap, /* Link to next entry */
#else
NULLIF,
#endif
"loopback", /* name */
NULLCHAR, /* description */
0x7f000001UL, /* addr 127.0.0.1 */
0xffffffffUL, /* broadcast 255.255.255.255 */
0xffffffffUL, /* netmask 255.255.255.255 */
MAXINT16, /* mtu No limit */
1, /* metric */
0, /* flags */
#ifdef NETROM
0, /* quality */
#endif
0, /* trace */
NULLCHAR, /* trfile */
NULLFILE, /* trfp */
-1, /* trsock */
NULLIF, /* forw */
#ifdef RXECHO
NULLIF, /* rxecho */
#endif
NULLPROC, /* rxproc */
NULLPROC, /* txproc */
NULLPROC, /* supv */
0, /* dev */
(int32 (*)(struct iface *, int, int, int32)) 0,
NULLFP ((struct iface *, int, int32)), /* (*iostatus) */
NULLFP ((struct iface *)), /* (*stop) */
NULLCHAR, /* hwaddr */
NULLCHAR, /* ipcall */
NULLCHAR, /* rmtaddr */
#ifdef AX25
NULL, /* ax25 protocol data */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
/* ax25 counters */
#endif /* AX25 */
&def_iftcp, /* tcp protocol data */
NULL, /* extension */
CL_NONE, /* type */
0, /* xdev */
0, /* port */
&Iftypes[0], /* iftype */
NULLFP ((struct mbuf *, struct iface *, uint32, int, int, int, int)), /* (*send) */
NULLFP ((struct iface *, const char *, char *, int16, struct mbuf *)), /* (*output) */
NULLFP ((struct iface *, struct mbuf *)), /* (*raw) */
NULLVFP ((struct iface *)), /* (*show) */
NULLFP ((struct iface *, struct mbuf *)), /* (*discard) */
NULLFP ((struct iface *, struct mbuf *)), /* (*echo) */
0, /* ipsndcnt */
0, /* rawsndcnt */
0, /* iprecvcnt */
0, /* rawrcvcnt */
0, /* lastsent */
0, /* lastrecv */
};
#ifdef ENCAP
/* Encapsulation pseudo-interface */
struct iface Encap =
{
NULLIF,
"encap", /* name */
NULLCHAR, /* description */
INADDR_ANY, /* addr 0.0.0.0 */
0xffffffffUL, /* broadcast 255.255.255.255 */
0xffffffffUL, /* netmask 255.255.255.255 */
MAXINT16, /* mtu No limit */
1, /* metric */
0, /* flags */
#ifdef NETROM
0, /* quality */
#endif
0, /* trace */
NULLCHAR, /* trfile */
NULLFILE, /* trfp */
-1, /* trsock */
NULLIF, /* forw */
#ifdef RXECHO
NULLIF, /* rxecho */
#endif
NULLPROC, /* rxproc */
NULLPROC, /* txproc */
NULLPROC, /* supv */
0, /* dev */
(int32 (*)(struct iface *, int, int, int32)) 0, /* (*ioctl) */
NULLFP ((struct iface *, int, int32)), /* (*iostatus) */
NULLFP ((struct iface *)), /* (*stop) */
NULLCHAR, /* hwaddr */
NULLCHAR, /* ipcall */
NULLCHAR, /* rmtaddr */
#ifdef AX25
NULL, /* ax25 protocol data */
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
/* ax25 counters */
#endif /* AX25 */
&def_iftcp, /* tcp protocol data */
NULL, /* extension */
CL_NONE, /* type */
0, /* xdev */
0, /* port */
&Iftypes[0], /* iftype */
ip_encap, /* (*send) */
NULLFP ((struct iface *, const char *, char *, int16, struct mbuf *)), /* (*output) */
NULLFP ((struct iface *, struct mbuf *)), /* (*raw) */
NULLVFP ((struct iface *)), /* (*show) */
NULLFP ((struct iface *, struct mbuf *)), /* (*discard) */
NULLFP ((struct iface *, struct mbuf *)), /* (*echo) */
0, /* ipsndcnt */
0, /* rawsndcnt */
0, /* iprecvcnt */
0, /* rawrcvcnt */
0, /* lastsent */
0, /* lastrecv */
};
#endif /*ENCAP*/
#if defined(DRSI) || defined(EAGLE) || defined(PC_EC) || defined(HAPN) || defined(PC100)
char Noipaddr[] = "IP address field missing, and ip address not set\n";
#endif
static struct cmds Ifcmds[] =
{
#ifdef AX25
{ "ax25", ifax25, 0, 0, NULLCHAR },
#endif
{ "broadcast", ifbroad, 0, 2, NULLCHAR },
{ "description", ifdescr, 0, 0, NULLCHAR },
{ "encapsulation", ifencap, 0, 2, NULLCHAR },
{ "forward", ifforw, 0, 2, NULLCHAR },
{ "ipaddress", ifipaddr, 0, 2, NULLCHAR },
{ "ipcall", ifipcall, 0, 2, NULLCHAR },
{ "linkaddress", iflinkadr, 0, 2, NULLCHAR },
{ "metric", ifmetric, 0, 2, NULLCHAR },
{ "mtu", ifmtu, 0, 2, NULLCHAR },
{ "netmask", ifnetmsk, 0, 2, NULLCHAR },
#ifdef RXECHO
{ "rxecho", ifrxecho, 0, 2, NULLCHAR },
#endif
{ "tcp", doiftcp, 0, 0, NULLCHAR },
{ NULLCHAR, NULL, 0, 0, NULLCHAR }
};
/* Set interface parameters */
int
doifconfig (int argc, char *argv[], void *p OPTIONAL)
{
struct iface *ifp;
int i, step = 2, newargc = argc;
if (argc < 2) {
for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
showiface (ifp);
return 0;
}
if ((ifp = if_lookup (argv[1])) == NULLIF) {
tprintf (Badinterface, argv[1]);
return 1;
}
if (argc == 2) {
showiface (ifp);
if (ifp->show != NULLVFP ((struct iface *)))
(*ifp->show) (ifp);
return 0;
}
if (argc == 3) {
dohelper (subcommands, Ifcmds, NULLCHAR, NULLCHAR, NULLCHAR);
return 1;
}
for (i = 2; i < argc - 1; i += step) {
step = (tolower (argv[i][0]) == 't') ? 3 : 2;
(void) subcmd (Ifcmds, newargc - 1, &argv[i - 1], ifp);
newargc -= step;
}
return 0;
}
/* Remove iface tracing to the current output socket */
void
removetrace ()
{
struct iface *ifp;
for (ifp = Ifaces; ifp; ifp = ifp->next)
if (ifp->trsock == Curproc->output) {
ifp->trace = 0;
/* We have to close the socket, because usesock() was called !*/
close_s (ifp->trsock);
ifp->trsock = -1;
}
}
static int
ishexaddr (char *str)
{
int k;
int l = (int) strlen (str);
if (l < 8 || l > 10)
return 0;
if (!strncasecmp (str, "0x", 2))
return 1;
for (k = 0; k < 8; k++) {
if (!isxdigit (str[k]))
return 0;
}
return 1;
}
/* Set interface IP address */
static int
ifipaddr (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
/* Do not allow loopback iface to be changed ! - WG7J */
if (ifp == &Loopback) {
tputs (nochangeIP);
return 0;
}
ifp->addr = (ishexaddr (argv[1])) ? (uint32) htol (argv[1]) : resolve (argv[1]);
return 0;
}
/* Set IP call sign */
static int
ifipcall (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
if (ifp->iftype == NULLIFT || ifp->iftype->scan == NULL) {
tputs (setIPcall);
return 1;
}
if (ifp->ipcall != NULLCHAR)
free (ifp->ipcall);
ifp->ipcall = mallocw ((unsigned) ifp->iftype->hwalen);
(void) (*ifp->iftype->scan) (ifp->ipcall, argv[1]);
return 0;
}
/* Set link (hardware) address */
static int
iflinkadr (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
if (ifp->iftype == NULLIFT || ifp->iftype->scan == NULL) {
tputs (setlinkaddr);
return 1;
}
if (ifp->hwaddr != NULLCHAR)
free (ifp->hwaddr);
ifp->hwaddr = mallocw ((unsigned) ifp->iftype->hwalen);
(void) (*ifp->iftype->scan) (ifp->hwaddr, argv[1]);
#if defined(MAILBOX) && defined(NETROM)
if (ifp == Nr_iface) /*the netrom call just got changed! - WG7J*/
setmbnrid ();
#endif
return 0;
}
/* Set interface broadcast address. This is actually done
* by installing a private entry in the routing table.
*/
static int
ifbroad (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
struct route *rp;
rp = rt_blookup (ifp->broadcast, 32);
if (rp != NULLROUTE && rp->iface == ifp)
(void) rt_drop (ifp->broadcast, 32);
ifp->broadcast = (ishexaddr (argv[1])) ? (uint32) htol (argv[1]): resolve (argv[1]);
(void) rt_add (ifp->broadcast, 32, 0L, ifp, 1L, 0L, 1);
return 0;
}
/* Set the network mask. This is actually done by installing
* a routing entry.
*/
static int
ifnetmsk (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
struct route *rp;
/* Remove old entry if it exists */
rp = rt_blookup (ifp->addr & ifp->netmask, (unsigned) mask2width (ifp->netmask));
if (rp != NULLROUTE)
(void) rt_drop (rp->target, rp->bits);
ifp->netmask = (ishexaddr (argv[1])) ? (uint32) htol (argv[1]) : resolve (argv[1]);
(void) rt_add (ifp->addr, (unsigned) mask2width (ifp->netmask), 0L, ifp, 0L, 0L, 0);
return 0;
}
/* Command to set interface encapsulation mode */
static int
ifencap (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
if (setencap (ifp, argv[1]) != 0) {
tprintf (encaperr, argv[1]);
return 1;
}
return 0;
}
/* Function to set encapsulation mode */
int
setencap (struct iface *ifp, const char *mode)
{
struct iftype *ift = (struct iftype *) 0;
if (mode != NULL) {
/* Configure the whole interface */
for (ift = &Iftypes[0]; ift->name != NULLCHAR; ift++)
if (strnicmp (ift->name, mode, strlen (mode)) == 0)
break;
if (ift->name == NULLCHAR)
return -1;
ifp->iftype = ift;
ifp->send = ift->send;
ifp->output = ift->output;
ifp->type = ift->type;
}
/* Set the tcp and ax25 interface parameters */
if (!ifp->tcp)
ifp->tcp = callocw (1, sizeof (struct iftcp));
init_iftcp (ifp->tcp);
#ifdef AX25
if (ift && ift->type == CL_AX25) {
if (!ifp->ax25)
ifp->ax25 = callocw (1, sizeof (struct ifax25));
init_ifax25 (ifp->ax25);
ifp->flags |= AX25_BEACON + MAIL_BEACON + AX25_DIGI + LOG_AXHEARD + LOG_IPHEARD;
}
#endif
return 0;
}
#ifdef RXECHO
/* Set interface IP address */
static int
ifrxecho (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
struct iface *rxecho;
if (!stricmp ("off", argv[1])) {
ifp->rxecho = NULLIF;
return 0;
};
if ((rxecho = if_lookup (argv[1])) == NULL) {
tprintf (Badinterface, argv[1]);
return 0;
};
if (ifp->type != rxecho->type) {
tprintf (notsametype, argv[1]);
return 0;
};
ifp->rxecho = rxecho;
return 0;
}
#endif /* RXECHO */
/* Set interface Maximum Transmission Unit */
static int
ifmtu (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
ifp->mtu = (int16) atoi (argv[1]);
#ifdef NETROM
/* Make sure NETROM mtu <= 236 ! - WG7J */
if (ifp == Nr_iface)
if (Nr_iface->mtu > NR4MAXINFO)
Nr_iface->mtu = NR4MAXINFO;
#endif
return 0;
}
/* Set interface metric for RIP - */
static int
ifmetric (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
ifp->iface_metric = atoi (argv[1]);
return 0;
}
/* Set interface forwarding */
static int
ifforw (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
ifp->forw = if_lookup (argv[1]);
if (ifp->forw == ifp)
ifp->forw = NULLIF;
return 0;
}
/*give a little description for each interface - WG7J*/
static int
ifdescr (int argc OPTIONAL, char *argv[], void *p)
{
struct iface *ifp = p;
#ifdef NETROM
#ifdef ENCAP
if ((ifp == &Loopback) || (ifp == &Encap) || (ifp == Nr_iface))
#else
if ((ifp == &Loopback) || (ifp == Nr_iface))
#endif /*ENCAP*/
#else /*NETROM*/
#ifdef ENCAP
if ((ifp == &Loopback) || (ifp == &Encap))
#else
if (ifp == &Loopback)
#endif /*ENCAP*/
#endif /*NETROM*/
return 0;
if (ifp->descr != NULLCHAR) {
free (ifp->descr);
ifp->descr = NULLCHAR; /* reset the pointer */
}
if (!strlen (argv[1]))
return 0; /* clearing the buffer */
ifp->descr = mallocw (strlen (argv[1]) + 2); /* allow for the EOL char etc */
strcpy (ifp->descr, argv[1]);
strcat (ifp->descr, "\n"); /* add the EOL char */
return 0;
}
/* Display the parameters for a specified interface */
static void
showiface (register struct iface *ifp)
{
char tmp[25];
tprintf (showfmt, ifp->name, inet_ntoa (ifp->addr), (int) ifp->mtu, ifp->iface_metric);
if (ifp->iftype == NULLIFT)
tputs (notset);
else {
tprintf ("%s%s\n", ifp->iftype->name, (ifp->rmtaddr != NULLCHAR) ? " (AXIP)" : "");
if (ifp->iftype->format != NULL && ifp->hwaddr != NULLCHAR) {
tprintf (showlink, (*ifp->iftype->format) (tmp, ifp->hwaddr));
#ifdef AX25
if (ifp->iftype->type == CL_AX25) {
if (ifp->ipcall != NULLCHAR)
tprintf (showIPcall, (*ifp->iftype->format) (tmp, ifp->ipcall));
tprintf (showlenirtt, (int) ifp->ax25->paclen, ifp->ax25->irtt);
if (ifp->ax25->bctext)
tprintf (showbctext, ifp->ax25->bctext);
if (ifp->rmtaddr != NULLCHAR) {
tprintf (showremote, (*ifp->iftype->format) (tmp, ifp->rmtaddr));
#ifdef AXIP
tprintf (showremoteIP, inet_ntoa (axipaddr[ifp->dev]));
#endif
}
}
#ifdef NETROM
else if (ifp == Nr_iface)
tprintf (" Alias %s\n", Nralias);
#endif
else
#endif
tputc ('\n');
}
}
tprintf (showflags, ifp->flags, ifp->trace, ifp->netmask, inet_ntoa (ifp->broadcast));
if (ifp->forw != NULLIF)
tprintf (showforw, ifp->forw->name);
#ifdef RXECHO
if (ifp->rxecho != NULLIF)
tprintf (showrxecho, ifp->rxecho->name);
#endif
tprintf (showsent, ifp->ipsndcnt, ifp->rawsndcnt, tformat (secclock () - ifp->lastsent));
tprintf (showrecv, ifp->iprecvcnt, ifp->rawrecvcnt, tformat (secclock () - ifp->lastrecv));
if (ifp->descr != NULLCHAR)
tprintf (showdescr, ifp->descr);
}
/* Command to detach an interface */
int
dodetach (int argc OPTIONAL, char *argv[], void *p OPTIONAL)
{
register struct iface *ifp;
if ((ifp = if_lookup (argv[1])) == NULLIF) {
tprintf (Badinterface, argv[1]);
return 1;
}
if (if_detach (ifp) == -1)
tputs (detnope);
return 0;
}
/* Detach a specified interface */
int
if_detach (register struct iface *ifp)
{
struct iface *iftmp;
struct route *rp, *rptmp;
int i, j;
struct ax_route *axr, *axr1;
struct arp_tab *ap, *ap1;
#ifdef ENCAP
if (ifp == &Loopback || ifp == &Encap)
#else
if (ifp == &Loopback)
#endif
return -1;
#ifdef AX25
/* Drop all ax25 routes that points to this interface */
for (axr = Ax_routes; axr != NULLAXR; axr = axr1) {
axr1 = axr->next; /* Save the next pointer */
if (axr->iface == ifp)
(void) ax_drop (axr->target, ifp, AX_NONSETUP);
/* axr will be undefined after ax_drop() */
}
#endif
/* Drop all ARP's that point to this interface */
for (i = 0; i < HASHMOD; ++i)
for (ap = Arp_tab[i]; ap != NULLARP; ap = ap1) {
ap1 = ap->next; /* Save the next pointer */
if (ap->iface == ifp)
arp_drop (ap);
/* ap will be undefined after arp_drop() */
}
/* Drop all routes that point to this interface */
if (R_default.iface == ifp)
(void) rt_drop (0L, 0);/* Drop default route */
for (i = 0; i < HASHMOD; i++) {
for (j = 0; j < 32; j++) {
for (rp = Routes[j][i]; rp != NULLROUTE; rp = rptmp) {
/* Save next pointer in case we delete this entry */
rptmp = rp->next;
if (rp->iface == ifp)
(void) rt_drop (rp->target, rp->bits);
}
}
}
/* Unforward any other interfaces forwarding to this one */
for (iftmp = Ifaces; iftmp != NULLIF; iftmp = iftmp->next) {
if (iftmp->forw == ifp)
iftmp->forw = NULLIF;
#ifdef RXECHO
if (iftmp->rxecho == ifp)
iftmp->rxecho = NULLIF;
#endif
}
/* Call device shutdown routine, if any */
if (ifp->stop != NULLFP ((struct iface *)))
(void) (*ifp->stop) (ifp);
killproc (ifp->rxproc);
killproc (ifp->txproc);
killproc (ifp->supv);
#ifdef NETROM
/*make sure that the netrom interface is properly detached
*fixed 11/15/91, Johan. K. Reinalda, WG7J/PA3DIS
*/
if (strcmp (ifp->name, "netrom") == 0) {
for (iftmp = Ifaces; iftmp; iftmp = iftmp->next)
iftmp->flags &= ~IS_NR_IFACE; /* this 'resets' active interfaces */
Nr_iface = NULLIF;
}
#endif
/* Free allocated memory associated with this interface */
if (ifp->name != NULLCHAR)
free (ifp->name);
if (ifp->hwaddr != NULLCHAR)
free (ifp->hwaddr);
if (ifp->ipcall != NULLCHAR)
free (ifp->ipcall);
free (ifp->tcp);
#ifdef AX25
if (ifp->ax25) {
if (ifp->ax25->bctext)
free (ifp->ax25->bctext);
free (ifp->ax25);
}
#endif
free (ifp->descr);
/* Remove from interface list */
if (ifp == Ifaces)
Ifaces = ifp->next;
else {
/* Search for entry just before this one
* (necessary because list is only singly-linked.)
*/
for (iftmp = Ifaces; iftmp != NULLIF; iftmp = iftmp->next)
if (iftmp->next == ifp)
break;
if (iftmp != NULLIF && iftmp->next == ifp)
iftmp->next = ifp->next;
}
/* Finally free the structure itself */
free ((char *) ifp);
return 0;
}
/* Given the ascii name of an interface, return a pointer to the structure,
* or NULLIF if it doesn't exist
*/
struct iface *
if_lookup (const char *name)
{
register struct iface *ifp;
for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
if (stricmp (ifp->name, name) == 0)
break;
return ifp;
}
/* Return iface pointer if 'addr' belongs to one of our interfaces,
* NULLIF otherwise.
* This is used to tell if an incoming IP datagram is for us, or if it
* has to be routed.
*/
struct iface *
ismyaddr (uint32 addr)
{
register struct iface *ifp;
for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
if (addr == ifp->addr)
break;
return ifp;
}
/* Given a network mask, return the number of contiguous 1-bits starting
* from the most significant bit.
*/
int
mask2width (uint32 mask)
{
int width, i;
width = 0;
for (i = 31; i >= 0; i--) {
if (!(mask & (1L << i)))
break;
width++;
}
return width;
}
/* return buffer with name + comment */
char *
if_name (struct iface *ifp, const char *comment)
{
char *result = mallocw (strlen (ifp->name) + strlen (comment) + 1);
strcpy (result, ifp->name);
return strcat (result, comment);
}
/* Raw output routine that tosses all packets. Used by dialer, tip, etc */
int
bitbucket (struct iface *ifp OPTIONAL, struct mbuf *bp)
{
free_p (bp);
return 0;
}
/* Set interface (or AX25) flags on 1 or all interfaces */
int
dosetflag (int argc, char *argv[], void *p OPTIONAL, int flagtoset, int AX25only)
{
struct iface *ifp;
if (argc < 2) {
for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
if (ifp->flags & flagtoset)
tprintf ("%s\n", ifp->name);
} else {
if ((argc == 3) && (strcmp (argv[1], "all") == 0)) {
for (ifp = Ifaces; ifp != NULLIF; ifp = ifp->next)
if (!AX25only || ifp->type == CL_AX25) {
if (strcmp (argv[2], "on") == 0)
ifp->flags |= flagtoset;
else if (strcmp (argv[2], "off") == 0)
ifp->flags &= ~flagtoset; /*lint !e502 */
else {
tputs ("Please use on or off.\n");
return 0;
}
}
return 0;
} else if ((ifp = if_lookup (argv[1])) == NULLIF) {
tprintf (Badinterface, argv[1]);
return 1;
}
if (AX25only && ifp->type != CL_AX25) {
tputs ("not an AX.25 interface\n");
return -1;
}
if (argc != 3)
ifp->flags ^= flagtoset;
else {
if (strcmp (argv[2], "on") == 0)
ifp->flags |= flagtoset;
else if (strcmp (argv[2], "off") == 0)
ifp->flags &= ~flagtoset; /*lint !e502 */
else
ifp->flags ^= flagtoset;
}
}
return 0;
}
/* attach a dummy interface. no parms for now. */
int
dummy_attach (argc, argv, p)
int argc OPTIONAL;
char *argv[] OPTIONAL;
void *p OPTIONAL;
{
struct iface *dummy;
uint32 n;
if ((n = resolve (argv[2])) == 0) {
tprintf (Badhost, argv[2]);
return 1;
}
dummy = (struct iface *) callocw (1, sizeof (struct iface));
dummy->addr = n;
dummy->iface_metric = 1;
/* The strdup is needed to keep the detach routine happy (it'll
* free the allocated memory)
*/
dummy->name = strdup (argv[1]);
dummy->hwaddr = mallocw (AXALEN);
memcpy (dummy->hwaddr, Mycall, AXALEN);
dummy->mtu = MAXINT16;
(void) setencap (dummy, "None");
dummy->next = Ifaces;
Ifaces = dummy;
return 0;
}